<?php

namespace app\api\controller;

use app\admin\model\Lines;
use app\common\controller\Api;
use app\common\library\RedisService;
use app\common\model\Config;

/**
 * • create by PhpStorm 2025/9/27 15:00
 *
 * • bus.com app\api\controller@Equipment
 *
 * • 行止之行 <xingzhi8711@gmail.com>
 *
 * • 设备接口
 */
class Equipment extends Api
{
    protected $noNeedLogin = ['*'];
    protected $noNeedRight = ['*'];

    public function init()
    {
        $code = $this->request->request("code");
        $station = $this->request->request("station");
        $list = \app\admin\model\Equipment::where('code', $code)->whereOr('station', $station)->find();
        if ($list) {
            $this->error('设备或站点已被关联过不要重复关联');
        }
        $equipment = \app\admin\model\Equipment::create([
            'code' => $code,
            'station' => $station,
            'name' => $station . "的站牌",
        ]);
        $this->success('ok', $equipment);
    }

    public function getLinesList1()
    {
        $redis=new RedisService();
        $listJson=$redis->get("en_ch_list");
        $listJson = json_decode( $listJson,true );
        $stationName = $this->request->request("station");
        $direction = $this->request->request("direction");
        if(!$stationName) $this->error('站点不存在');
        $stationName1=$stationName;
        $diffAdd1=0;
        $diffAdd2=0;
        $redis = new RedisService();
        $keys = $redis->hgetKeys("station_line_time_tables_".$stationName);
        $result = [];
        foreach ($keys as $key) {
            $lines = Lines::get($key);
            $wd=date("N");
            $runWeek=explode(",",$lines["run_week"]);
            if(!in_array($wd,$runWeek)){
                continue;
            }
            $list=$redis->getHash("station_line_time_tables_".$stationName,$key);
            foreach ($list as $line) {
                if($stationName=="胶架厂"){
                    if($line['direction']==$direction && date("H:i")<$line['times']){
                        $result[] = [
                            "line_info" => [
                                'line_id' => $lines->id,
                                'start_station' =>  $lines->first,
                                // 'start_station' =>  $lines->line.$lines->first,
                                'end_station' => $lines->last
                            ],
                            'next_departure' => [
                                'departure_time' => date("H:i",strtotime($line['times']) + 60),
                                // 'departure_time' => date("H:i",strtotime($line['times'])+$diffAdd2*60+60),
                                'remaining_minutes' => ceil((strtotime($line['times'])-strtotime(date("H:i")))/60)+$diffAdd1,//剩余几分钟
                                'is_today' => true  // 标记为今天班次
                            ],
                            'arrival_info' => []
                        ];
                        break;
                    }
                }elseif(date("H:i")<$line['times']){
                    // if( $lines->first ==  )
                    $result[] = [
                        "line_info" => [
                            'line_id' => $lines->id,
                            'start_station' => $lines->first,
                            // 'start_station' => $lines->line.$lines->first,
                            // 'start_station_en' => 
                            'end_station' => $lines->last
                        ],
                        'next_departure' => [
                            'departure_time' => date("H:i",strtotime($line['times']) + 60),
                            // 'departure_time' => date("H:i",strtotime($line['times'])+$diffAdd2*60+60),
                            'remaining_minutes' => ceil((strtotime($line['times'])-strtotime(date("H:i")))/60)+$diffAdd1,//剩余几分钟
                            'is_today' => true  // 标记为今天班次
                        ],
                        'arrival_info' => []
                    ];
                    break;
                }
            }
        }
        $equipment = \app\admin\model\Equipment::where('station', $stationName)->find();
        $redis->set("equipment_".$stationName."_last_request",time());
        $this->success('ok', ['list' => $result, 'equipment' => $equipment]);
    }
    
    public function getLinesList()
    {
        $redis=new RedisService();
        $listJson=$redis->get("en_ch_list");
        $listJson = json_decode( $listJson,true );
        $stationName = $this->request->request("station");
        $direction = $this->request->request("direction");
        $stationName1=$stationName;
        $diffAdd1=0;
        $diffAdd2=0;
        $redis = new RedisService();
        $keys = $redis->hgetKeys("station_line_time_tables_".$stationName);
        $result = [];
        foreach ($keys as $key) {
            $lines = Lines::get($key);
            $wd=date("N");
            $runWeek=explode(",",$lines["run_week"]);
            if(!in_array($wd,$runWeek)){
                continue;
            }
            $list=$redis->getHash("station_line_time_tables_".$stationName,$key);
            foreach ($list as $line) {
                
                foreach ( $listJson as $k => $v ){
                    if( $lines->first == $v['en'] ){
                        $lines->first_en = $v['zh'];
                    }
                    if( $lines->last == $v['en'] ){
                        $lines->last_en = $v['zh'];
                    }
                    $syTimes = ceil((strtotime($line['times'])-strtotime(date("H:i")))/60)+$diffAdd1;
                    if( $v['key'] == 2 ){
                        $syTxt['cn']  =  str_replace( "#min#",$syTimes,$v['en'] );
                        $syTxt['en']  =  str_replace( "#min#",$syTimes,$v['zh'] );
                    }
                }
                if(date("H:i")<$line['times']){
                    // if( $lines->first ==  )
                    $syTimes = ceil((strtotime($line['times'])-strtotime(date("H:i")))/60)+$diffAdd1;
                    $result[] = [
                        "line_info" => [
                            'line_id' => $lines->id,
                            'start_station' => $lines->first,
                            // 'start_station' => $lines->line.$lines->first,
                            'start_station_en' => $lines->first_en,
                            'end_station' => $lines->last,
                            'end_station_en' => $lines->last_en
                        ],
                        'next_departure' => [
                            'departure_time' => date("H:i",strtotime($line['times']) + 60),
                            // 'departure_time' => date("H:i",strtotime($line['times'])+$diffAdd2*60+60),
                            'remaining_minutes' => $syTimes,
                            'remaining_minutes_cn' => $syTxt['cn'],
                            'remaining_minutes_en' => $syTxt['en'],
                            'is_today' => true 
                        ],
                        'arrival_info' => []
                    ];
                    break;
                }
            }
        }
        $equipment = \app\admin\model\Equipment::where('station', $stationName)->find();
        foreach ( $listJson as $k => $v ){
            if( $equipment['station'] == $v['en'] ){
                 $equipment['station_en']  =  $v['zh'];
            }
        }
        usort($result, function($a, $b) {
            return $a['next_departure']['remaining_minutes'] - $b['next_departure']['remaining_minutes'];
        });
        $redis->setHash("equipment_last_request_time",$stationName,time());
        $this->success('ok', ['list' => $result, 'equipment' => $equipment]);
    }
    
    /*public function getLinesList()
    {
        $stationName = $this->request->request("station");
        $direction = $this->request->request("direction");

        if (!$stationName) {
            $this->error('请输入站点名称');
        }
        $diffAdd=0;
        $stationNameI=$stationName;
        if($stationName=="注塑") {
            $stationName="胶架厂";

            $direction=0;
            $diffAdd=1;
        }
        if($stationName=="零件") {
            $stationName="胶架厂";
            $direction=1;
            $diffAdd=1;
        }

        // 1. 获取经过该站点的所有线路
        $stationLines = \app\admin\model\BusStation::where('station_name', $stationName)
            ->select();
        if ($direction !== null) {
            $filteredStationLines = [];
            foreach ($stationLines as $station) {
                $line = \app\admin\model\BusLine::find($station['line_id']);
                if ($line && $line['direction'] == $direction) {
                    $filteredStationLines[] = $station;

                }

            }
            $stationLines = $filteredStationLines;
        }

        if (!$stationLines) {
            $this->error('该站点暂无线路经过');
        }

        $result = [];

        // 2. 对每条线路计算到站时间和下一趟发车时间
        foreach ($stationLines as $station) {
            $lineId = $station['line_id'];

            // 获取线路信息
            $line = \app\admin\model\BusLine::find($lineId);
            if (!$line) {
                continue;
            }

            // 获取下一趟发车时间
            $nextDeparture = $this->getNextDepartureTime($lineId,$diffAdd);

            // 如果没有班次信息，跳过该线路
            if (!$nextDeparture) {
                continue;
            }

            // 获取到站时间
            $arrivalInfo = $this->getArrivalTime($lineId, $stationName);

            $result[] = [
                'line_info' => [
                    'line_id' => $line['id'],
                    'line_number' => $line['line_number'],
                    'line_name' => $line['line_name'],
                    'direction' => $line['direction'],
                    'start_station' => $line['start_station'],
                    'end_station' => $line['end_station'],
                    'station_order' => $station['station_order']
                ],
                'next_departure' => $nextDeparture,
                'arrival_info' => $arrivalInfo
            ];
        }

        if (!$result) {
            $this->error('暂无最新班次信息！');
        }

        // 对结果进行排序：今天的班次在前，明天的班次在后
        usort($result, function ($a, $b) {
            $aIsToday = !isset($a['next_departure']['is_tomorrow']);
            $bIsToday = !isset($b['next_departure']['is_tomorrow']);

            if ($aIsToday && !$bIsToday) {
                return -1; // a是今天，b是明天，a排前面
            } elseif (!$aIsToday && $bIsToday) {
                return 1; // a是明天，b是今天，b排前面
            } else {
                // 都是今天或都是明天，按发车时间排序
                $aTime = $a['next_departure']['departure_time'];
                $bTime = $b['next_departure']['departure_time'];
                return strcmp($aTime, $bTime);
            }
        });
        $redis=new RedisService();
        $equipment = \app\admin\model\Equipment::where('station', $stationNameI)->find();
        $redis->set("equipment_".$stationNameI."_last_request",time());
        $this->success('ok', ['list' => $result, 'equipment' => $equipment]);
    }*/

    /**
     * ◦ 获取下一趟发车时间（优化班次逻辑，特别处理周日）
     */
    private function getNextDepartureTime($lineId, $diffAdd)
    {
        $currentTime = date('H:i:s');
        $currentHour = date('H');
        $currentWeekday = date('N'); // 1-7 周一到周日

        // 修复：如果当前时间超过22点（晚上10点），直接返回明天首班
        if ($currentHour >= 22) {
            $tomorrowWeekday = $currentWeekday == 7 ? 1 : $currentWeekday + 1;
            $tomorrowSchedules = \app\admin\model\BusSchedule::where('line_id', $lineId)
                ->where(function ($query) use ($tomorrowWeekday) {
                    // 处理各种周期类型
                    $this->buildWeekdayCondition($query, $tomorrowWeekday);
                })
                ->order('departure_time', 'asc')
                ->select();

            if ($tomorrowSchedules) {
                $firstSchedule = $tomorrowSchedules[0];
                return [
                    'departure_time' => date("H:i:s", strtotime($firstSchedule['departure_time']) + ($diffAdd ? $diffAdd + 1 : 0) * 60),
                    'remaining_minutes' => '明日首班',
                    'is_tomorrow' => true,
                    'weekdays' => $firstSchedule['weekdays'],
                    'schedule_type' => $firstSchedule['schedule_type']
                ];
            }
            return null;
        }

        // 1. 先查找今天符合条件的班次
        $todaySchedules = \app\admin\model\BusSchedule::where('line_id', $lineId)
            ->where(function ($query) use ($currentWeekday) {
                // 处理各种周期类型
                $this->buildWeekdayCondition($query, $currentWeekday);
            })
            ->where('departure_time', '>', $currentTime)
            ->order('departure_time', 'asc')
            ->select();

        if ($todaySchedules) {
            $nextSchedule = $todaySchedules[0];
            return [
                'departure_time' => date("H:i:s", strtotime($nextSchedule['departure_time']) + ($diffAdd ? $diffAdd + 1 : 0) * 60),
                'remaining_minutes' => $this->calculateTimeDiff($currentTime, $nextSchedule['departure_time'], $diffAdd),
                'weekdays' => $nextSchedule['weekdays'],
                'schedule_type' => $nextSchedule['schedule_type'],
                'is_today' => true  // 标记为今天班次
            ];
        }

        // 2. 如果今天没有后续班次，查找明天的班次
        $tomorrowWeekday = $currentWeekday == 7 ? 1 : $currentWeekday + 1;
        $tomorrowSchedules = \app\admin\model\BusSchedule::where('line_id', $lineId)
            ->where(function ($query) use ($tomorrowWeekday) {
                // 处理各种周期类型
                $this->buildWeekdayCondition($query, $tomorrowWeekday);
            })
            ->order('departure_time', 'asc')
            ->select();

        if ($tomorrowSchedules) {
            $firstSchedule = $tomorrowSchedules[0];
            return [
                'departure_time' => date("H:i:s", strtotime($firstSchedule['departure_time']) + ($diffAdd ? $diffAdd + 1 : 0) * 60),
                'remaining_minutes' => '明日首班',
                'is_tomorrow' => true,
                'weekdays' => $firstSchedule['weekdays'],
                'schedule_type' => $firstSchedule['schedule_type']
            ];
        }

        return null;
    }

    /**
     * ◦ 构建星期条件（统一处理各种周期类型，特别处理周日）
     */
    private function buildWeekdayCondition($query, $weekday)
    {
        // 处理范围类型 (1-5, 1-6, 1-7)
        $query->whereOr(function ($q) use ($weekday) {
            $q->where('weekdays', '1-5')
                ->where("{$weekday} >= 1 AND {$weekday} <= 5");
        })
            ->whereOr(function ($q) use ($weekday) {
                $q->where('weekdays', '1-6')
                    ->where("{$weekday} >= 1 AND {$weekday} <= 6");
            })
            ->whereOr(function ($q) use ($weekday) {
                $q->where('weekdays', '1-7')
                    ->where("{$weekday} >= 1 AND {$weekday} <= 7");
            })
            // 处理仅周日的情况
            ->whereOr(function ($q) use ($weekday) {
                $q->where('weekdays', '7')
                    ->where("{$weekday} = 7");
            })
            // 处理仅周六的情况
            ->whereOr(function ($q) use ($weekday) {
                $q->where('weekdays', '6')
                    ->where("{$weekday} = 6");
            })
            // 处理周六和周日的情况
            ->whereOr(function ($q) use ($weekday) {
                $q->where('weekdays', '6,7')
                    ->where("{$weekday} IN (6,7)");
            })
            // 处理逗号分隔的特定日期 (如: 1,3,5 或 2,4,6,7)
            ->whereOr(function ($q) use ($weekday) {
                $q->where('weekdays', 'like', '%,%')
                    ->where("FIND_IN_SET({$weekday}, REPLACE(weekdays, ' ', ''))");
            });

        return $query;
    }

    /**
     * ◦ 获取到站时间（基于预设时间计算）
     */
    private function getArrivalTime($lineId, $stationName)
    {
        // 获取站点信息
        $station = \app\admin\model\BusStation::where('line_id', $lineId)
            ->where('station_name', $stationName)
            ->find();

        if (!$station) {
            return null;
        }

        $currentTime = date('H:i:s');
        $currentHour = date('H');
        $currentWeekday = date('N');

        // 修复：如果当前时间超过22点，使用明天的班次计算到站时间
        if ($currentHour >= 22) {
            $tomorrowWeekday = $currentWeekday == 7 ? 1 : $currentWeekday + 1;
            $tomorrowSchedules = \app\admin\model\BusSchedule::where('line_id', $lineId)
                ->where(function ($query) use ($tomorrowWeekday) {
                    $this->buildWeekdayCondition($query, $tomorrowWeekday);
                })
                ->order('departure_time', 'asc')
                ->select();

            if ($tomorrowSchedules) {
                $firstSchedule = $tomorrowSchedules[0];

                // 计算预计到达时间（明天首班车）
                $tomorrowDate = date('Y-m-d', strtotime('+1 day'));
                $departureTimestamp = strtotime($tomorrowDate . ' ' . $firstSchedule['departure_time']);
                $estimatedArrivalTimestamp = $departureTimestamp + ($station['estimated_minutes'] * 60);
                $currentTimestamp = time();

                $remainingSeconds = $estimatedArrivalTimestamp - $currentTimestamp;

                return [
                    'data_source' => 'preset',
                    'estimated_arrival_seconds' => $remainingSeconds,
                    'estimated_arrival_minutes' => ceil($remainingSeconds / 60),
                    'departure_time' => $firstSchedule['departure_time'],
                    'station_order' => $station['station_order'],
                    'schedule_type' => $firstSchedule['schedule_type'],
                    'is_tomorrow' => true
                ];
            }
            return null;
        }

        // 查找最近已发车的班次
        $latestSchedules = \app\admin\model\BusSchedule::where('line_id', $lineId)
            ->where(function ($query) use ($currentWeekday) {
                // 处理各种周期类型
                $this->buildWeekdayCondition($query, $currentWeekday);
            })
            ->where('departure_time', '<=', $currentTime)
            ->order('departure_time', 'desc')
            ->select();

        if ($latestSchedules) {
            $latestSchedule = $latestSchedules[0];

            // 计算预计到达时间
            $departureTimestamp = strtotime(date('Y-m-d') . ' ' . $latestSchedule['departure_time']);
            $estimatedArrivalTimestamp = $departureTimestamp + ($station['estimated_minutes'] * 60);
            $currentTimestamp = time();

            $remainingSeconds = $estimatedArrivalTimestamp - $currentTimestamp;

            // 如果车辆已经过站，返回0
            if ($remainingSeconds < 0) {
                $remainingSeconds = 0;
            }

            return [
                'data_source' => 'preset',
                'estimated_arrival_seconds' => $remainingSeconds,
                'estimated_arrival_minutes' => ceil($remainingSeconds / 60),
                'departure_time' => $latestSchedule['departure_time'],
                'station_order' => $station['station_order'],
                'schedule_type' => $latestSchedule['schedule_type']
            ];
        }

        return null;
    }

    /**
     * ◦ 计算时间差（分钟）
     */
    private function calculateTimeDiff($startTime, $endTime, $diffAdd)
    {
        $start = strtotime($startTime);
        $end = strtotime($endTime);
        $diff = round(($end - $start) / 60) + $diffAdd;
        return $diff > 0 ? $diff : 0;
    }
}